﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Security;

namespace ExcelRefresh
{
    public class EventLogListenerEx : TraceListener
    {
        private readonly EventLogEntryType _logType = EventLogEntryType.Information;
        private readonly EventLog _eventLog;

        public EventLogListenerEx(string logType)
        {
            var eventLogName = "Application";
            var eventLogSource = string.Empty;

            foreach (var part in from pair in logType.Split(';')
                                 let parts = pair.Split('=')
                                 where parts.Length == 2
                                 select parts)
            {
                switch (part[0].ToLower())
                {
                    case "log": eventLogName = part[1]; break;
                    case "source": eventLogSource = part[1]; break;
                    case "type": _logType = (EventLogEntryType)Enum.Parse(typeof(EventLogEntryType), part[1]); break;
                }
            }

            eventLogSource = eventLogSource ?? System.Reflection.Assembly.GetCallingAssembly().GetName().Name;

            try
            {
                if (EventLog.SourceExists(eventLogSource))
                    EventLog.DeleteEventSource(eventLogSource);

                EventLog.CreateEventSource(eventLogSource, eventLogName);
            }
            catch (SecurityException)
            {
                Trace.WriteLine("Not enough credentials to create an event source - switching to Application.");
                eventLogSource = "Application";
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Unexpected exception while checking for an event source: " + ex);
                eventLogSource = "Application";
            }
            _eventLog = new EventLog(eventLogName, System.Environment.MachineName, eventLogSource);
        }


        public override void Write(string message)
        {
            if (message.EndsWith(": 0 : ")) return;
            _eventLog.WriteEntry(message, _logType);
        }

        public override void WriteLine(string message)
        {
            Write(message + Environment.NewLine);
        }

        public override void WriteLine(string message, string category)
        {
            EventLogEntryType entryType;
            
            if(!Enum.TryParse(category, true, out entryType))
                entryType = _logType;

            _eventLog.WriteEntry(message, entryType);
        }

        public override void Fail(string message)
        {
            _eventLog.WriteEntry(message, EventLogEntryType.Error);
        }

        public override void Fail(string message, string detailMessage)
        {
            _eventLog.WriteEntry(
                message + Environment.NewLine + detailMessage,
                EventLogEntryType.Error);
        }
    }
}